﻿/*
 * Copyright 2012 Rene Prost, Registrite ja Infosüsteemide Keskus 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

using System.CodeDom;
using System.Collections.Generic;
using System.Web.Services.Description;
using System.Xml;
using Xtee.CodeDom.CodeBuilders;
using Xtee.CodeDom.CodeStatements;
using Xtee.CodeDom.MetaInfo;
using Xtee.Core;
using Xtee.Core.Services.Description;
using Xtee.Core.Utils;

namespace Xtee.CodeDom.DeclarationBuilders
{
    public class OperationMetainfoListDeclarationBuilder : ListBasedCodeTypeDeclarationBuilder
    {
        private PropertyMember namespaceProperty =   new PropertyMember("Namespace", typeof (string));
        public OperationMetainfoListDeclarationBuilder(Description description) : base(description)
        { 
        }

        public override IEnumerable<CodeTypeDeclaration> Build()
        {
            var clazz = new CodeTypeDeclaration("XteeOperationMetainfoList"); 
            clazz.BaseTypes.Add(typeof (List<OperationInfo>));
            clazz.BaseTypes.Add(typeof (IXteeOperationMetainfoList));
            namespaceProperty.AddTo(clazz); 
            clazz.Members.Add(BuildConstructor());
            yield return clazz; 
        }

        private CodeConstructor BuildConstructor()
        {
            var addStatemenets = BuildCodeObjects<CodeExpressionStatement>();
            var constr = new CodeConstructor();
            constr.Name = "XteeOperationMetainfoList";
            constr.Attributes = MemberAttributes.Public; 
            constr.Statements.Add(BuildNameSpaceAssign());
            constr.Statements.AddRange(addStatemenets.ToArray());
            return constr;
        }

        private CodeAssignStatement BuildNameSpaceAssign()
        {
            return 
                new CodeAssignStatement(
                    new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), namespaceProperty.FieldName),
                    new CodeSnippetQuotedExpression(StringUtils.ToCodeNamespace(new XmlQualifiedName(string.Empty, description.Port.TargetNamespace.Namespace))));
        } 
        public override CodeObject BuildCodeObject(string operationName, SchemaObjectClassInfo input, SchemaObjectClassInfo inputHeader, SchemaObjectClassInfo output, SchemaObjectClassInfo outputHeader)
        {
            var create = new CodeObjectCreateExpression(typeof(OperationInfo), new CodeSnippetQuotedExpression(operationName), GeTypeOf(input.NameInfo.GlobalName), GeTypeOf(output.NameInfo.GlobalName), GeTypeOf(inputHeader.NameInfo.GlobalName), GeTypeOf(outputHeader.NameInfo.GlobalName));
            return new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "Add", create));
        }
        private CodeSnippetExpression GeTypeOf(string type)
        {
            return new CodeSnippetExpression(string.Format("typeof({0})",type));
        } 
    }
}
